package cn.congine.wizarpos.mall.tenpay;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.codec.binary.Hex;

import cn.congine.wizarpos.mall.model.SaleOrder;
import cn.congine.wizarpos.mall.model.SaleOrderItem;
import cn.congine.wizarpos.mall.model.WxOrder;
import cn.congine.wizarpos.mall.model.WxOrderDetail;
import cn.congine.wizarpos.mall.tenpay.util.XMLUtil;
import cn.congine.wizarpos.mall.utils.WxSignUtil;

/**
 * 准备微信生成的预支付回话标识
 * 
 * @author GuZhenjuan
 *
 */
public class PaymentPackage {
	// 用户公众号下唯一ID
	private String openid;
	// 公众号ID
	private String appid;
	// 商品描述
	private String body;
	// 商户号
	private String mch_id;
	// 随机字符串
	private String nonce_str;
	// 商户订单号
	private String out_trade_no;
	// 终端IP
	private String spbill_create_ip;
	// 总金额
	private Integer total_fee;
	// 通知地址
	private String notify_url;
	// 交易类型
	private String trade_type = "JSAPI";
	// package 签名
	private String sign;

	public String getOpenid() {
		return openid;
	}

	public void setOpenid(String openid) {
		this.openid = openid;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	public String getBody() {
		return body;
	}

	public void setBody(String body) {
		this.body = body;
	}

	public String getMch_id() {
		return mch_id;
	}

	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}

	public String getNonce_str() {
		return nonce_str;
	}

	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}

	public String getOut_trade_no() {
		return out_trade_no;
	}

	public void setOut_trade_no(String out_trade_no) {
		this.out_trade_no = out_trade_no;
	}

	public String getSpbill_create_ip() {
		return spbill_create_ip;
	}

	public void setSpbill_create_ip(String spbill_create_ip) {
		this.spbill_create_ip = spbill_create_ip;
	}

	public Integer getTotal_fee() {
		return total_fee;
	}

	public void setTotal_fee(Integer total_fee) {
		this.total_fee = total_fee;
	}

	public String getNotify_url() {
		return notify_url;
	}

	public void setNotify_url(String notify_url) {
		this.notify_url = notify_url;
	}

	public String getTrade_type() {
		return trade_type;
	}

	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}

	/**
	 * 生成请求微信预支付回话标识的签名
	 * 
	 * @param paternerKey
	 */
	public void toSign(String paternerKey) {
		String sign = null;
		String msg = toString(false) + "&key=" + paternerKey;
		MessageDigest md = null;
		byte[] array = null;
		try {
			md = MessageDigest.getInstance("MD5");
			array = md.digest(msg.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		sign = new String(Hex.encodeHex(array));
		sign = sign.toUpperCase();
		setSign(sign);
	}

	public void assemble(WxOrder order, List<WxOrderDetail> orderItems) {
		StringBuffer _body = new StringBuffer();
		Iterator<WxOrderDetail> it = orderItems.iterator();
		while (it.hasNext()) {
			_body.append(it.next().getProductName());
			if (it.hasNext()) {
				_body.append(",");
			}
		}
		setBody(_body.toString());
		setOut_trade_no(order.getOrderId());
		setTotal_fee(order.getAmount());
		setOpenid(order.getOpenId());
	}

	public void assemble(SaleOrder order, String Items, String openId) {
		setBody(Items);
		setOut_trade_no(order.getOrderNo());
		setTotal_fee(order.getAmount());
		setOpenid(openId);
	}

	private String toString(boolean urlEncode) {
		StringBuffer sb = new StringBuffer();
		Map<String, String> data = getData();
		SortedSet<String> keys = new TreeSet<String>(data.keySet());
		Iterator<String> it = keys.iterator();
		while (it.hasNext()) {
			String key = it.next();
			String value = data.get(key);
			sb.append(key).append("=");
			if (urlEncode) {
				sb.append(WxSignUtil.urlEncode(value));
			} else {
				sb.append(value);
			}
			if (it.hasNext()) {
				sb.append("&");
			}
		}
		return sb.toString();
	}

	/**
	 * 请求微信生成的预支付回话标识的必须字段
	 * 
	 * @return
	 */
	private Map<String, String> getData() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("appid", getAppid());
		map.put("body", getBody());
		map.put("nonce_str", getNonce_str());
		map.put("mch_id", getMch_id());
		map.put("openid", getOpenid());
		map.put("out_trade_no", getOut_trade_no());
		map.put("spbill_create_ip", getSpbill_create_ip());
		map.put("notify_url", getNotify_url());
		map.put("total_fee", getTotal_fee().toString());
		map.put("trade_type", getTrade_type());
		return map;
	}

	/**
	 * 包含签名的xml字串，用于微信支付接口请求
	 * 
	 * @return
	 */
	public String getPackageXML() {
		Map<String, String> map = getData();
		map.put("sign", getSign());
		String xmlData = XMLUtil.MapToXml(map);
		return xmlData;
	}

}
